#ifndef __RELIABLE_CHANNEL_H__
#define __RELIABLE_CHANNEL_H__

#include "BaseChannel.h"

namespace LiteNetLib
{
    class PendingPacket
    {
    private:
        NetPacket *m_packet = nullptr;
        int64_t m_timeStamp = 0;
        bool m_isSent = false;

    public:
        PendingPacket() = default;
        ~PendingPacket();
        void init(NetPacket *packet);
        bool trySend(int64_t currentTime, NetPeer *netPeer);
        bool clear();
    };

    class ReliableChannel : public BaseChannel
    {
    private:
        std::mutex outgoingAckMutex;
        NetPacket *m_outgoingAcks;

        std::mutex pendingPacketMutex;
        PendingPacket m_pendingPackets[64];

        NetPacket *m_receivedPackets[64] = { nullptr };
        bool m_earlyReceived[64] = { false };

        int32_t m_localSeqence;
        int32_t m_remoteSequence;
        int32_t m_localWindowStart;
        int32_t m_remoteWindowStart;
        bool m_mustSendAcks;

        DeliveryMethod m_deliveryMethod;
        bool m_ordered;
        int m_windowSize;
        uint8_t m_id;

    private:
        void processAck(const char *dataBuff, uint32_t dataSize);

    protected:
        virtual bool sendNextPackets() override;
        virtual bool processData(const char* dataBuff, uint32_t dataSize) override;

    public:
        ReliableChannel(NetPeer *netPeer, bool ordered, uint8_t id);
        virtual void clear() override;
        virtual ~ReliableChannel();
    };

} // namespace LiteNetLib

#endif
